<html>
<script>
/*
基本类型（undefined、null、boolean、number、string）和引用类型（object）是不一样的。如果从一个变量向另一个变量复制基本类型的值，会在变量对象上创建一个新值，然后把该值赋值到为新变量分配的位置上，此后这两个变量可以参与任何操作而不会互相影响。而当从一个变量向另一个变量复制引用类型的值时，同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中，不同的是，这个值的副本实际上是一个指针，而这个指针指向存储在堆中的一个对象。复制操作结束后，两个变量实际上将引用同一个对象。因此，改变其中一个变量，就会影响另一个变量：
var a = [0, 1, 2, 3];
var b = a;
b.push(4, 5, 6);
console.log(a); // [0, 1, 2, 3, 4, 5, 6]

而ECMAScript中所有函数的参数都是按值传递的，也就是说，把函数外部的值复制给函数内部的参数，就和把值从一个变量复制到另一个变量一样！弄清楚了这一点，我们再回到上面的代码。
当没有执行nums = tmp.concat(nums);这行代码时，数组a和函数rotate的参数nums都引用着同一个地址，于是它们的值一起改变；当执行这行代码后，nums指向了一个新的地址，无论它指向哪里，此时的它已经和数组a没有任何关系，也就是说a的值在这一刻之后不会再变化了。

*/
var rotate = function(nums, k) {
  k %= nums.length;
  var tmp = [];
  if (k)
    tmp = nums.slice(-k);
  nums.splice(-k, k);

  /* Jerry 2016-01-22 10:34AM - 因此不能采取赋值的方式，而是
  调用自身引用对象的方法
  nums = tmp.concat(nums);

  按引用传递就是函数外的变量和函数里的参数引用同一块地址，它们的值无论什么情况都一起变动。而代码中当参数指向一个新的对象后，和函数外的变量脱离关系了，所以JavaScript不是按引用传递的；可以对比下c、c++等语言，它们如果按引用传递的话，就会一起变化，就算参数被重新赋值


  */
  Array.prototype.unshift.apply(nums, tmp);
};

var num = [0,1,2,3,4,5];
rotate(num, 3);
console.log(num); // 0,1,2 - not expected!
</script>
</html>